package org.freedoit.util;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.freedoit.FreeDoit;
import org.freedoit.common.shared.SharedTask;
import org.freedoit.common.util.FreeDoitDataUtils;
import org.freedoit.common.util.SharedConstants;
import org.freedoit.gui.DoitFrame;
import org.freedoit.om.Task;

public class Utils {
    public static java.awt.Color getComponentColor(String key) {
        Object value = UIManager.get(key);
        if(value instanceof ColorUIResource) {
            return (ColorUIResource)value;
        }
        
        return null;
    }
    public static void main(String[] args) {
        Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
        
        if (fonts != null && fonts.length > 0) {
            for (Font f : fonts) {
                if (f.getName().toLowerCase().contains("simsun")) {
                    System.out.println(f.getName());
                    //break;
                }
            }
        }
    }
    
    public static java.sql.Date getToday() {
        return new java.sql.Date(System.currentTimeMillis());
    }
    
    public static java.sql.Date getTomorrow() {
        return getDate(1);
    }
    
    public static java.sql.Date getTheDayAfterTomorrow() {
        return getDate(2);
    }
    
    public static java.sql.Date getDate(int cmpToday) {
        Calendar c = Calendar.getInstance();
        c.roll(Calendar.DATE, cmpToday);
        return new java.sql.Date(c.getTimeInMillis());
    }
    
    public static java.sql.Time getNextTimePointFromNow(boolean includeHalf) {
        return getNextTimePoint(new java.sql.Time(System.currentTimeMillis()), includeHalf);
    }
    
    public static java.sql.Time getNextTimePointFromNow() {
        return getNextTimePoint(new java.sql.Time(System.currentTimeMillis()));
    }
    
    public static java.sql.Time getNextTimePoint(java.sql.Time now) {
        return getNextTimePoint(now, true);
    }
    
    public static java.sql.Time getNextTimePoint(java.sql.Time now, boolean includeHalf) {
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        
        if (includeHalf && c.get(Calendar.MINUTE) < 30) {
            c.set(Calendar.MINUTE, 30);
        } else {
            c.set(Calendar.MINUTE, 0);
            c.roll(Calendar.HOUR_OF_DAY, 1);
        }
        
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        
        return new java.sql.Time(c.getTimeInMillis());
    }

    public static Task fromSharedData(SharedTask sharedTask) {
        Task newTask = new Task(sharedTask.getTaskId(), sharedTask.getTaskTypeId(), sharedTask.getProjectId(),
                FreeDoitDataUtils.decodeString(sharedTask.getTaskName()), 
                FreeDoitDataUtils.decodeString(sharedTask.getDescription()), 
                sharedTask.getStartDate(), sharedTask.getDueDate(),
                sharedTask.getStartTime(), sharedTask.getDueTime(), sharedTask.getFinished(), 
                FreeDoitDataUtils.decodeString(sharedTask.getTaskTag()),
                sharedTask.getStatus(), null);
        
        return newTask;
    }

    public static SharedTask toSharedData(Task task) {
        SharedTask newTask = new SharedTask(task.getSerialNo(), task.getTaskId(), task.getTaskTypeId(), task.getProjectId(),
                FreeDoitDataUtils.encodeString(task.getTaskName()), 
                FreeDoitDataUtils.encodeString(task.getDescription()),
                task.getStartDate(), task.getDueDate(), task.getFinishDate(),
                task.getStartTime(), task.getDueTime(), task.getFinishTime(), task.getFinished(), 
                FreeDoitDataUtils.encodeString(task.getTaskTag()),
                task.getStatus());
        
        return newTask;
    }
    
    public static void displayAtCentralScreen(Window window) {
        
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension size = window.getSize();
        int x = (screenSize.width - size.width) / 2;
        int y = (screenSize.height - size.height) / 2;
        window.setLocation( x, y );

    }
    
    public static int compareSQLDate(java.sql.Date date1, java.sql.Date date2) {
        return compareDateByThreeField(date1, date2, Calendar.YEAR, Calendar.MONTH, 
                Calendar.DAY_OF_MONTH);
    }
    
    public static int compareSQLTime(java.sql.Time time1, java.sql.Time time2) {
        return compareDateByThreeField(time1, time2, Calendar.HOUR_OF_DAY,
                Calendar.MINUTE, Calendar.SECOND);
    }
    
    public static boolean isSameSQLDate(java.sql.Date date1, java.sql.Date date2) {
        return isSameDateByThreeField(date1, date2, Calendar.YEAR, Calendar.MONTH, 
                Calendar.DAY_OF_MONTH);
    }
    
    public static boolean isSameSQLTime(java.sql.Time time1, java.sql.Time time2) {
        return isSameDateByThreeField(time1, time2, Calendar.HOUR_OF_DAY,
                Calendar.MINUTE, Calendar.SECOND);
    }
    
    private static boolean isSameDateByThreeField(java.util.Date date1, java.util.Date date2,
            int firstCmpFiled, int secondCmpField, int thirdCmpField) {
        if (date1 == null) {
            if (date2 == null) {
                return true;
            } else {
                return false;
            }
        } else {
            if (date2 == null) {
                return false;
            } else {
                Calendar c1 = Calendar.getInstance();
                c1.setTime(date1);
                Calendar c2 = Calendar.getInstance();
                c2.setTime(date2);
                
                return (c1.get(firstCmpFiled) == c2.get(firstCmpFiled)
                        && c1.get(secondCmpField) == c2.get(secondCmpField)
                        && c1.get(thirdCmpField) == c2.get(thirdCmpField));
            }
        }
    }
    
    public static String fillSpace(String str, int count) {
        if (str == null || count <= 0) {
            return str;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < count; i ++) {
            sb.append("  ");// insert two space
        }
        
        sb.insert(count, str); // insert into middle
        
        return sb.toString();
        
    }
    
    public static String sendHttpPostMessage(String messageIn, String url) {
        // send request
        HttpPost httppost = new HttpPost(url);

        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
        String key = FreeDoitDataUtils.generateRandomAESKey();
        String encryptedKey = EncryptEngine.doEncrypt(key);
        String message = FreeDoitDataUtils.encryptByAES(messageIn, key);
        if (message == null) {
            System.err.println("Fail to encrypt data");
            return null;
        }

        nameValuePairs.add(new BasicNameValuePair(SharedConstants.DATA_KEY, message));
        nameValuePairs.add(new BasicNameValuePair(SharedConstants.KEY, encryptedKey));
        //hp.setParameter(Constants.JSON_DATA_KEY, message);

        String responseBody = null;
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        UrlEncodedFormEntity e = null;
        try {
            e = new UrlEncodedFormEntity(nameValuePairs);
            httppost.setEntity(e);
            responseBody = FreeDoit.getHttpClient().execute(httppost, responseHandler);
        } catch (ClientProtocolException ex) {
            Logger.getLogger(DoitFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(DoitFrame.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (e != null) {
                try {
                    EntityUtils.consume(e);
                } catch (IOException ex) {
                    Logger.getLogger(DoitFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

        if (responseBody != null) { //decrypt
            responseBody = FreeDoitDataUtils.decryptByAES(responseBody, key);
        }
        
        return responseBody;
    }
    
    private static int compareDateByThreeField(java.util.Date date1, java.util.Date date2,
            int firstCmpFiled, int secondCmpField, int thirdCmpField) {
        if (date1 == null) {
            if (date2 == null) {
                return 0;
            } else {
                return -1;
            }
        } else {
            if (date2 == null) {
                return 1;
            } else {
                Calendar c1 = Calendar.getInstance();
                c1.setTime(date1);
                Calendar c2 = Calendar.getInstance();
                c2.setTime(date2);
                
                int y1 = c1.get(firstCmpFiled);
                int y2 = c2.get(firstCmpFiled);
                if (y1 < y2) {
                    return -1;
                } else if (y1 > y2) {
                    return 1;
                } else {
                    int m1 = c1.get(secondCmpField);
                    int m2 = c2.get(secondCmpField);
                    if (m1 < m2) {
                        return -1;
                    } else if (m1 > m2) {
                        return 1;
                    } else {
                        int d1 = c1.get(thirdCmpField);
                        int d2 = c2.get(thirdCmpField);
                        return (d1 < d2 ? -1 : (d1 > d2 ? 1 : 0));
                    }
                }
            }
        }
    }
}
